package kr.co.onc.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
import net.sf.json.util.JSONUtils;

public class JsonUtil
{
	/**
	 * JSON 설정 정보
	 * @return JsonConfig
	 */
	public static JsonConfig config()
	{
		class DateJsonValueProcessor implements JsonValueProcessor
		{
			private final DateFormat dateFormat;
			
			public DateJsonValueProcessor()
			{
				dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			}
			public Object processArrayValue(Object arg0, JsonConfig arg1)
			{
				if(arg0 != null)
					return dateFormat.format(arg0);
				else
					return null;
			}
			public Object processObjectValue(String arg0, Object arg1, JsonConfig arg2)
			{
				return processArrayValue(arg1, arg2);
			}
		}
		
		JsonConfig config = new JsonConfig();
		config.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor());
		config.registerJsonValueProcessor(java.sql.Date.class, new DateJsonValueProcessor());
		config.registerJsonValueProcessor(java.sql.Timestamp.class, new DateJsonValueProcessor());
		
		return config;
	}
	
	
	/**
	 * Map 을 Json 문자열로 변환
	 * @param param Map 객체
	 * @return Json 문자열로 바뀐 Map 자료
	 */
	public static String Map2String(Map<String, Object> param)
	{
		if(param == null || param.isEmpty())
		{
			return "{}";
		}
		else
		{
			JSONObject json = JSONObject.fromObject(param, JsonUtil.config());
			
			return json.toString();
		}
	}
	
	/**
	 * Json 문자열을 Map으로 변환
	 * @param param Json 문자열
	 * @return Map 객체
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> String2Map(String param)
	{
		JsonConfig config = new JsonConfig();
		config.setArrayMode(JsonConfig.MODE_LIST);
		
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] {"yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd"}));
		
		Map<String, Object> ret;
		try
		{
			JSONObject json = JSONObject.fromObject(param, config);
			ret = (Map<String, Object>)JSONObject.toBean(json, HashMap.class);
		}
		catch(Exception e)
		{
			ret = new HashMap<String, Object>();
		}
		return ret;
	}
	
	/**
	 * List 를 Json 문자열로 변환
	 * @param param List 객체
	 * @return Json 문자열로 바뀐 List 자료
	 */
	public static String List2String(List<?> param)
	{
		if(param == null)
			return "{}";
		else
		{
			JSONArray jsonArray = JSONArray.fromObject(param, JsonUtil.config());
			return jsonArray.toString();
		}
	}
	
	/**
	 * Json 문자열을 List로 변환
	 * @param param Json 문자열
	 * @param classObject 데이터 자료형
	 * @return List 객체
	 */
	@SuppressWarnings({ "unchecked", "rawtypes", "deprecation" })
	public static List<?> String2List(String param, Class classObject)
	{
		JsonConfig config = new JsonConfig();
		config.setArrayMode(JsonConfig.MODE_LIST);
		config.setRootClass(classObject);
		
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] {"yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd"}));
		
		Map classMap = new HashMap();
		
		List<?> ret;
		try
		{
			JSONArray jsonArray = JSONArray.fromObject(param, config);
			ret = (List<Object>)JSONArray.toList(jsonArray, classObject, classMap);
		}
		catch(Exception e)
		{
			ret = new ArrayList<Object>();
		}
		finally
		{
		}
		
		return ret;
	}
	
	/**
	 * Object 를 Json 문자열로 변환
	 * @param param 객체
	 * @return Json 문자열로 바뀐 Object 자료
	 */
	public static String Object2String(Object param)
	{
		JsonUtil.config();
		
		if(param == null)
			return "{}";
		else
		{
			JSONArray jsonArray = JSONArray.fromObject(param, JsonUtil.config());
			String ret = jsonArray.toString();
			
			if(ret != null && !ret.isEmpty() && ret.substring(0, 1).equals("[")) ret = ret.substring(1);
			if(ret != null && !ret.isEmpty() && ret.substring(ret.length() - 1, ret.length()).equals("]")) ret = ret.substring(0, ret.length() - 1);
			
			return ret;
		}
	}
	
	/**
	 * Json 문자열을 Object 로 변환
	 * @param param Json 문자열
	 * @param objectClass 데이터 자료형
	 * @return Object 객체
	 */
	@SuppressWarnings("rawtypes")
	public static Object String2Object(String param, Class objectClass)
	{
		if(param != null) param = param.trim();
		if(param != null && param.substring(0, 1).equals("["))
			param = param.substring(1);
		if(param != null && param.substring(param.length() - 1, param.length()).equals("]"))
			param = param.substring(0, param.length() - 1);
		
		JsonConfig config = new JsonConfig();
		config.setArrayMode(JsonConfig.MODE_LIST);
		config.setRootClass(objectClass);
		
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] {"yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd"}));
		
		try
		{
			JSONObject json = JSONObject.fromObject(param, config);
			return JSONObject.toBean(json, objectClass);
		}
		catch(Exception e)
		{
			return null;
		}
	}
}